const express = require('express');
const fs = require('fs');
const path = require('path');
const nodemailer = require('nodemailer');
const svgCaptcha = require('svg-captcha');
const bcrypt = require('bcrypt');
const session = require('express-session');

const app = express();
const port = 3111;

// 使用session中间件
app.use(session({
    secret: 'your-secret-key',
    resave: false,
    saveUninitialized: true,
    cookie: { secure: false } // 在生产环境中应设置为true，并使用HTTPS
}));

// 解析JSON请求体
app.use(express.json());
app.use(express.urlencoded({ extended: true }));

// 初始化数据存储
let users = {};

// 配置文件路径
const configPath = path.join(__dirname, 'data', 'users.json');
const DATA_DIR = path.join(__dirname, 'data');
const USERS_PATH = path.join(DATA_DIR, 'users.json');

// 确保数据目录存在
const ensureDataDirectory = () => {
    if (!fs.existsSync(DATA_DIR)) {
        fs.mkdirSync(DATA_DIR);
    }
};

// 通用文件读取函数
const readDataFile = (filePath, defaultValue = {}) => {
    try {
        if (fs.existsSync(filePath)) {
            const data = fs.readFileSync(filePath, 'utf8');
            return JSON.parse(data);
        }
        fs.writeFileSync(filePath, JSON.stringify(defaultValue, null, 2));
        return defaultValue;
    } catch (error) {
        console.error(`读取文件 ${filePath} 失败:`, error);
        return defaultValue;
    }
};

// 读取或初始化用户数据文件
if (fs.existsSync(USERS_PATH)) {
    const userData = fs.readFileSync(USERS_PATH, 'utf8');
    try {
        users = JSON.parse(userData);
    } catch (error) {
        console.error("无法解析用户数据文件:", error);
    }
} else {
    console.error("用户数据文件不存在，将创建新的文件");
    fs.writeFileSync(USERS_PATH, JSON.stringify({}, null, 2), 'utf8');
}

// 初始化数据
const initializeData = () => {
    ensureDataDirectory();
    users = readDataFile(USERS_PATH);
};

initializeData();

// 配置SMTP邮件发送器
const transporter = nodemailer.createTransport({
    service: '163', // 使用服务名称而非SMTP地址
    host: 'smtp.163.com',
    port: 465,
    secure: true, // 使用SSL/TLS加密连接
    auth: {
        user: 'a217945sujiner@163.com', // 替换为您的邮箱地址
        pass: 'BHXzf4i7sWz3uDAy' // 替换为您的邮箱授权码
    }
});

// 存储验证码和过期时间
const verificationCodes = {};
const captchaStore = {};

// API路由，处理注册请求
app.post('/api/register', async (req, res) => {
    const { email, password, confirmPassword, captcha } = req.body;

    if (!email || !password || !confirmPassword || !captcha) {
        return res.status(400).json({ message: "无效的数据格式" });
    }

    // 验证图形验证码
    const sessionId = req.session ? req.session.id : req.ip; // 使用session ID或IP作为键
    const storedCaptcha = captchaStore[sessionId];

    if (!storedCaptcha || storedCaptcha.text !== captcha.toLowerCase() || storedCaptcha.expiresAt < Date.now()) {
        return res.status(400).json({ message: "验证码错误或已过期" });
    }

    // 删除已使用的验证码
    delete captchaStore[sessionId];

    // 检查密码是否匹配
    if (password !== confirmPassword) {
        return res.status(400).json({ message: "两次输入的密码不一致" });
    }

    // 检查邮箱是否已被注册
    if (Object.values(users).some(user => user.email === email)) {
        return res.status(400).json({ message: "该邮箱已被注册" });
    }

    // 生成随机验证码
    const code = Math.floor(100000 + Math.random() * 900000).toString();

    // 存储验证码及其过期时间（5分钟）
    verificationCodes[email] = {
        code,
        expiresAt: Date.now() + 5 * 60 * 1000
    };

    // 发送验证码邮件
    const mailOptions = {
        from: '"注册系统" <a217945sujiner@163.com>', // 发件人名称和地址
        to: email,
        subject: '注册验证码',
        text: `您好，您的验证码是 ${code}，有效期为5分钟。`
    };

    transporter.sendMail(mailOptions, (error, info) => {
        if (error) {
            console.error("邮件发送失败:", error);
            return res.status(500).json({ message: "验证码发送失败，请稍后再试" });
        }
        console.log("邮件发送成功:", info.response);
        res.status(200).json({ message: "验证码已发送" });
    });
});

// API路由，处理验证码验证请求
app.post('/api/verify-code', (req, res) => {
    const { email, code, password } = req.body;

    if (!email || !code || !password) {
        return res.status(400).json({ message: "无效的数据格式" });
    }

    // 获取存储的验证码信息
    const storedCodeInfo = verificationCodes[email];
    if (!storedCodeInfo || storedCodeInfo.code !== code || storedCodeInfo.expiresAt < Date.now()) {
        return res.status(400).json({ message: "验证码错误或已过期" });
    }

    // 删除已使用的验证码
    delete verificationCodes[email];

    // 生成唯一标识符（UUID）
    const userId = Date.now().toString(36) + Math.random().toString(36).substr(2, 5);

    // 哈希密码
    bcrypt.hash(password, 10)
        .then(hashedPassword => {
            // 存储新用户信息
            users[userId] = {
                email,
                id: userId,
                password: hashedPassword // 添加哈希密码到用户对象
            };

            // 写回用户数据文件
            fs.writeFileSync(configPath, JSON.stringify(users, null, 2), 'utf8');

            res.status(200).json({ message: "验证成功", id: userId });
        })
        .catch(error => {
            console.error("哈希密码时发生错误:", error);
            res.status(500).json({ message: "服务器内部错误" });
        });
});

// API路由，返回指定用户的ID
app.get('/api/user/:id', (req, res) => {
    const id = req.params.id;
    const user = users[id];

    if (!user) {
        return res.status(404).json({ message: "未找到用户信息" });
    }
    res.json({ id: user.id, email: user.email });
});

// API路由，生成图形验证码
app.get('/api/generate-captcha', (req, res) => {
    const captcha = svgCaptcha.createMathExpr({
        size: 4, // 数字数量
        ignoreChars: '0oO1ilI', // 忽略相似字符
        noise: 2, // 噪声线数量
        color: true, // 彩色验证码
        mathMin: 1,
        mathMax: 9
    });

    // 存储验证码及其过期时间（5分钟）
    const sessionId = req.session ? req.session.id : req.ip; // 使用session ID或IP作为键
    captchaStore[sessionId] = {
        text: captcha.text.toLowerCase(),
        expiresAt: Date.now() + 5 * 60 * 1000
    };

    res.type('svg').status(200).send(captcha.data);
});

// API路由，验证图形验证码
app.post('/api/verify-captcha', (req, res) => {
    const { captcha } = req.body;

    if (!captcha) {
        return res.status(400).json({ message: "无效的数据格式" });
    }

    const sessionId = req.session ? req.session.id : req.ip; // 使用session ID或IP作为键
    const storedCaptcha = captchaStore[sessionId];

    if (!storedCaptcha || storedCaptcha.text !== captcha.toLowerCase() || storedCaptcha.expiresAt < Date.now()) {
        return res.status(400).json({ message: "验证码错误或已过期" });
    }

    // 删除已使用的验证码
    delete captchaStore[sessionId];

    res.status(200).json({ message: "验证成功" });
});

// API路由，处理登录请求
app.post('/api/login', async (req, res) => {
    const { email, password, captcha } = req.body;

    if (!email || !password || !captcha) {
        return res.status(400).json({ message: "无效的数据格式" });
    }

    // 验证图形验证码
    const sessionId = req.session ? req.session.id : req.ip; // 使用session ID或IP作为键
    const storedCaptcha = captchaStore[sessionId];

    if (!storedCaptcha || storedCaptcha.text !== captcha.toLowerCase() || storedCaptcha.expiresAt < Date.now()) {
        return res.status(400).json({ message: "验证码错误或已过期" });
    }

    // 删除已使用的验证码
    delete captchaStore[sessionId];

    // 查找用户
    const user = Object.values(users).find(u => u.email === email);

    if (!user) {
        return res.status(400).json({ message: "邮箱、密码或验证码错误，请重试" });
    }

    // 验证密码
    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
        return res.status(400).json({ message: "邮箱、密码或验证码错误，请重试" });
    }

    req.session.userId = user.id;
    req.session.isLoggedIn = true;

    res.status(200).json({ message: "登录成功", id: user.id });
});

// API路由，处理更新邮箱请求
app.post('/api/update-email', async (req, res) => {
    const { email, password } = req.body;

    if (!email || !password) {
        return res.status(400).json({ message: "无效的数据格式" });
    }

    const userId = req.session.userId;
    const user = users[userId];

    if (!user) {
        return res.status(404).json({ message: "未找到用户信息" });
    }

    // 验证密码
    const isPasswordValid = await bcrypt.compare(password, user.password);
    if (!isPasswordValid) {
        return res.status(400).json({ message: "密码错误，请重试" });
    }

    // 检查新邮箱是否已被注册
    if (Object.values(users).some(u => u.email === email && u.id !== userId)) {
        return res.status(400).json({ message: "该邮箱已被注册" });
    }

    // 更新邮箱
    user.email = email;

    // 写回用户数据文件
    fs.writeFileSync(configPath, JSON.stringify(users, null, 2), 'utf8');

    res.status(200).json({ message: "邮箱更新成功" });
});

// API路由，处理更改密码请求
app.post('/api/change-password', async (req, res) => {
    const { oldPassword, newPassword } = req.body;

    if (!oldPassword || !newPassword) {
        return res.status(400).json({ message: "无效的数据格式" });
    }

    const userId = req.session.userId;
    const user = users[userId];

    if (!user) {
        return res.status(404).json({ message: "未找到用户信息" });
    }

    // 验证旧密码
    const isOldPasswordValid = await bcrypt.compare(oldPassword, user.password);
    if (!isOldPasswordValid) {
        return res.status(400).json({ message: "旧密码错误，请重试" });
    }

    // 哈希新密码
    const hashedNewPassword = await bcrypt.hash(newPassword, 10);

    // 更新密码
    user.password = hashedNewPassword;

    // 写回用户数据文件
    fs.writeFileSync(configPath, JSON.stringify(users, null, 2), 'utf8');

    res.status(200).json({ message: "密码更改成功" });
});

// 添加版本数据存储
const versionDataPath = path.join(__dirname, 'data', 'versions.json');
const USER_VERSIONS_DIR = path.join(__dirname, 'shuju'); // 用户版本数据存储目录

// 确保用户数据目录存在
const ensureUserVersionDir = (userId) => {
    const userDir = path.join(USER_VERSIONS_DIR, userId);
    if (!fs.existsSync(userDir)) {
        fs.mkdirSync(userDir, { recursive: true });
    }
    return userDir;
};

// 读取或初始化版本数据文件
if (fs.existsSync(versionDataPath)) {
    const data = fs.readFileSync(versionDataPath, 'utf8');
    try {
        versionData = JSON.parse(data);
    } catch (error) {
        console.error("无法解析版本数据文件:", error);
    }
} else {
    fs.writeFileSync(versionDataPath, JSON.stringify({}, null, 2), 'utf8');
}

// 修改版本更新路由
app.post('/api/update-version-info', (req, res) => {
    const userId = req.session.userId;
    if (!userId) return res.status(401).json({ message: "未授权访问" });

    // 创建用户专属目录
    const userDir = ensureUserVersionDir(userId);
    const versionFilePath = path.join(userDir, 'version.json');

    // 创建带元数据的新版本对象
    const versionData = {
        ...req.body,
        uuid: userId,
        timestamp: new Date().toISOString()
    };

    // 覆盖写入文件
    try {
        fs.writeFileSync(versionFilePath, JSON.stringify(versionData, null, 2));
        res.status(200).json({ 
            message: "版本信息更新成功",
            data: versionData
        });
    } catch (error) {
        console.error("写入版本文件失败:", error);
        res.status(500).json({ message: "服务器内部错误" });
    }
});

// 修改版本信息获取路由
app.get('/api/version/:userId', (req, res) => {
    const userId = req.params.userId;
    const versionFilePath = path.join(USER_VERSIONS_DIR, userId, 'version.json');

    try {
        if (fs.existsSync(versionFilePath)) {
            const data = JSON.parse(fs.readFileSync(versionFilePath, 'utf8'));
            return res.json(data);
        }
        res.status(404).json({ message: "未找到版本信息" });
    } catch (error) {
        console.error("读取版本文件失败:", error);
        res.status(500).json({ message: "服务器内部错误" });
    }
});

// 提供静态文件服务（包括HTML文件）
app.use(express.static(path.join(__dirname, 'public')));

// 启动服务器
app.listen(port, () => {
    console.log(`
 _______  _______  _______  _______  _______  _______  _______  _______  _______  _______ 
(  ____ \\(  ___  )(       )(  ____ \\(  ____ \\(  ___  )(       )(  ____ \\(  ____ \\(  ____ \\
| (    \\/| (   ) || () () || (    \\/| (    \\/| (   ) || () () || (    \\/| (    \\/| (    \\/
| (__    | (___) || || || || (__    | |      | (___) || || || || (__    | |      | (_____ 
|  __)   |  ___  || |(_)| ||  __)   | |      |  ___  || |(_)| ||  __)   | |      (_____  \\
| (      | (   ) || |   | || (      | |      | (   ) || |   | || (      | |            ) |
| (____/\\| )   ( || )   ( || (____/\\| (____/\\| )   ( || )   ( || (____/\\| (____/\\/\\____) |
(_______/|/     \\||/     \\|(_______/(_______/|/     \\||/     \\|(_______/(_______/\\_______/
                                                                                           
    潇宇 - API版本更新和用户注册
    ==========================
    服务器运行在 http://localhost:${port}
    版本信息API已启用 http://localhost:${port}/api/version/:key
    ==========================
    `);
    console.log(`
    潇宇 - API版本更新和用户注册
    ==========================
    登录API在 http://localhost:${port}/api/login
    注册API在 http://localhost:${port}/api/register
    验证码验证API在 http://localhost:${port}/api/verify-code
    用户信息API在 http://localhost:${port}/api/user/:id
    图形验证码生成API在 http://localhost:${port}/api/generate-captcha
    图形验证码验证API在 http://localhost:${port}/api/verify-captcha
    更新邮箱API在 http://localhost:${port}/api/update-email
    更改密码API在 http://localhost:${port}/api/change-password
    ==========================
    `);
});